
using _RobotInspection.Entities;
using _RobotInspection.Interfaces;
using _RobotInspection.Models;
using Microsoft.AspNetCore.Mvc;
using Models;
using RobotInspection.Entities;
using RobotInspection.Interfaces;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RobotInspection.Services
{
    /// <summary>
    /// 点检记录自动生成服务
    /// </summary>
    public class InspectionRecordGeneratorService : IInspectionRecordGeneratorService
    {
        private readonly IRepository _repository;
        private readonly ISqlSugarClient _db;

        public InspectionRecordGeneratorService(IRepository repository, ISqlSugarClient db)
        {
            _repository = repository;
            _db = db;
        }

        /// <summary>
        /// 根据计划周期自动生成点检记录
        /// </summary>
        public async Task<ActionResult<ApiResponse<object>>> GenerateInspectionRecords(DateTime? targetDate = null)
        {
            try
            {
                var date = targetDate ?? DateTime.Today;
                var generatedCount = 0;

                // 获取所有启用的点检计划
                var activePlans = await _db.Queryable<inspection_plans>()
                    .Where(p => p.is_active == 1 &&
                               (p.start_date == null || p.start_date <= date) &&
                               (p.end_date == null || p.end_date >= date))
                    .ToListAsync();

                foreach (var plan in activePlans)
                {
                    if (ShouldGenerateForDate(plan, date))
                    {
                        var result = await GenerateInspectionRecordsForPlan(plan.id, date);
                        //if (result.Value?.Success == true)
                        //{
                        //    generatedCount++;
                        //}
                    }
                }

                return new OkObjectResult(ApiResponse<object>.Success(new { GeneratedPlansCount = generatedCount, TargetDate = date }, $"成功为 {generatedCount} 个计划生成点检记录"));
            }
            catch (Exception ex)
            {
                return new OkObjectResult(ApiResponse<object>.Error($"生成点检记录失败: {ex.Message}"));
            }
        }

        /// <summary>
        /// 为指定计划生成点检记录
        /// </summary>
        public async Task<ActionResult<ApiResponse<object>>> GenerateInspectionRecordsForPlan(long planId, DateTime targetDate)
        {
            try
            {
                // 获取计划信息
                var plan = await _db.Queryable<inspection_plans>()
                    .FirstAsync(p => p.id == planId);

                if (plan == null)
                {
                    throw new BusinessException(404, "计划不存在");
                }

                // 检查是否已经生成过该日期的任务
                var existingTasks = await _db.Queryable<inspection_tasks>()
                    .Where(t => t.plan_id == planId && t.task_date.Date == targetDate.Date)
                    .ToListAsync();

                if (existingTasks.Any())
                {
                    return new OkObjectResult(ApiResponse<object>.Error($"计划 {plan.plan_name} 在 {targetDate:yyyy-MM-dd} 的任务已存在"));
                }

                // 获取计划关联的设备和项目
                var planItems = await _db.Queryable<inspection_plan_items>()
                    .Where(pi => pi.plan_id == planId)
                    .ToListAsync();

                if (!planItems.Any())
                {
                    return new OkObjectResult(ApiResponse<object>.Error($"计划 {plan.plan_name} 没有关联的点检项目"));
                }

                // 获取计划关联的用户（假设从plan_user_relations表获取）
                var planUsers = await _db.Queryable<plan_user_relations>()
                    .Where(pu => pu.plan_id == planId)
                    .ToListAsync();

                // 注意：现在允许计划没有直接指派用户，因为可能使用设备绑定的用户
                // if (!planUsers.Any())
                // {
                //     return new OkObjectResult(ApiResponse<object>.Error($"计划 {plan.plan_name} 没有指派用户"));
                // }

                var generatedTasksCount = 0;
                var generatedRecordsCount = 0;

                // 按设备分组生成任务
                var equipmentGroups = planItems.GroupBy(pi => pi.equipment_id);

                foreach (var equipmentGroup in equipmentGroups)
                {
                    var equipmentId = equipmentGroup.Key;
                    var items = equipmentGroup.ToList();

                    // 优先获取设备绑定的用户，如果没有则使用计划指派的用户
                    var equipmentUsers = await _db.Queryable<equipment_user_relations>()
                        .Where(eur => eur.equipment_id == equipmentId && eur.is_active == 1)
                        .ToListAsync();

                    List<long> assignedUserIds;
                    if (equipmentUsers.Any())
                    {
                        // 使用设备绑定的用户
                        assignedUserIds = equipmentUsers.Select(eu => eu.user_id).ToList();
                    }
                    else if (planUsers.Any())
                    {
                        // 使用计划指派的用户
                        assignedUserIds = planUsers.Select(pu => pu.user_id).ToList();
                    }
                    else
                    {
                        // 既没有设备绑定用户，也没有计划指派用户，跳过此设备
                        continue;
                    }

                    // 为指派的用户创建任务
                    foreach (var userId in assignedUserIds)
                    {
                        // 创建点检任务
                        var task = new inspection_tasks
                        {
                            plan_id = planId,
                            task_date = targetDate,
                            equipment_id = equipmentId,
                            assigned_user_id = userId,
                            task_status = 0, // 待执行
                            created_at = DateTime.Now,
                            updated_at = DateTime.Now
                        };

                        var taskId = await _db.Insertable(task).ExecuteReturnIdentityAsync();
                        generatedTasksCount++;

                        // 为任务创建点检记录
                        foreach (var item in items)
                        {
                            if (item.item_id.HasValue)
                            {
                                var record = new inspection_records
                                {
                                    task_id = taskId,
                                    item_id = item.item_id.Value,
                                    result_status = 3, // 待处理
                                    created_at = DateTime.Now,
                                    updated_at = DateTime.Now
                                };

                                await _db.Insertable(record).ExecuteCommandAsync();
                                generatedRecordsCount++;
                            }
                        }
                    }
                }

                return new OkObjectResult(ApiResponse<object>.Success(new
                {
                    PlanId = planId,
                    PlanName = plan.plan_name,
                    TargetDate = targetDate,
                    TasksCount = generatedTasksCount,
                    RecordsCount = generatedRecordsCount
                }, $"成功为计划 {plan.plan_name} 生成 {generatedTasksCount} 个任务和 {generatedRecordsCount} 条点检记录"));
            }
            catch (Exception ex)
            {
                return new OkObjectResult(ApiResponse<object>.Error($"为计划生成点检记录失败: {ex.Message}"));
            }
        }

        /// <summary>
        /// 判断指定日期是否应该为计划生成任务
        /// </summary>
        private bool ShouldGenerateForDate(inspection_plans plan, DateTime date)
        {
            // 检查节假日设置
            if (plan.is_holiday == 0 && IsHoliday(date))
            {
                return false;
            }

            switch (plan.plan_type)
            {
                case 1: // 日点检
                    return ShouldGenerateDaily(plan, date);
                case 2: // 周点检
                    return ShouldGenerateWeekly(plan, date);
                case 3: // 月点检
                    return ShouldGenerateMonthly(plan, date);
                case 4: // 一次性点检
                    return ShouldGenerateOneTime(plan, date);
                default:
                    return false;
            }
        }

        /// <summary>
        /// 判断是否为节假日（简单实现，可根据实际需求扩展）
        /// </summary>
        private bool IsHoliday(DateTime date)
        {
            // 简单判断周末
            return date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
        }

        /// <summary>
        /// 日点检生成逻辑
        /// </summary>
        private bool ShouldGenerateDaily(inspection_plans plan, DateTime date)
        {
            // 每天都生成，或者根据frequency_value间隔天数生成
            if (plan.frequency_value.HasValue && plan.frequency_value > 1)
            {
                var daysSinceStart = (date - (plan.start_date ?? date)).Days;
                return daysSinceStart % plan.frequency_value.Value == 0;
            }
            return true;
        }

        /// <summary>
        /// 周点检生成逻辑
        /// </summary>
        private bool ShouldGenerateWeekly(inspection_plans plan, DateTime date)
        {
            // 根据specific_period判断是否为指定的星期几
            if (!string.IsNullOrEmpty(plan.specific_period))
            {
                // specific_period可能包含星期几的信息，如"1,3,5"表示周一、周三、周五
                var dayOfWeek = (int)date.DayOfWeek;
                if (dayOfWeek == 0) dayOfWeek = 7; // 将周日从0改为7

                return plan.specific_period.Split(',').Contains(dayOfWeek.ToString());
            }

            // 默认每周一生成
            return date.DayOfWeek == DayOfWeek.Monday;
        }

        /// <summary>
        /// 月点检生成逻辑
        /// </summary>
        private bool ShouldGenerateMonthly(inspection_plans plan, DateTime date)
        {
            // 根据specific_period判断是否为指定的日期
            if (!string.IsNullOrEmpty(plan.specific_period))
            {
                if (int.TryParse(plan.specific_period, out int targetDay))
                {
                    // 处理月末情况
                    var daysInMonth = DateTime.DaysInMonth(date.Year, date.Month);
                    var actualTargetDay = Math.Min(targetDay, daysInMonth);
                    return date.Day == actualTargetDay;
                }
            }

            // 默认每月1号生成
            return date.Day == 1;
        }

        /// <summary>
        /// 一次性点检生成逻辑
        /// </summary>
        private bool ShouldGenerateOneTime(inspection_plans plan, DateTime date)
        {
            // 只在开始日期生成一次
            return plan.start_date.HasValue && plan.start_date.Value.Date == date.Date;
        }
    }
}